import { _decorator, Label, Node, tween, Tween, UITransform, v3, Vec3, Widget } from 'cc';
import { AudioManager } from '../../../frame/component/audio-manager';
import { BaseUI } from '../../../frame/component/ui.base';
import GGameDC from '../../manager/game.data.game.center';
import GGameAssets from '../../manager/game.game.assets';
const { ccclass, property } = _decorator;

@ccclass('GTransition')
export class GTransition extends BaseUI {
	private ui_left: UITransform;
	private ui_round_list: UITransform[] = [];
	private ui_round_box: UITransform;

	private va_left: mtec.cc.VecAssist;
	private va_round_list: mtec.cc.VecAssist[] = [];
	private va_round_box: mtec.cc.VecAssist;

	private last_show_round = 1;
	private item_space: number;
	private calculate_v3 = v3(0, 0, 0);

	protected initAfterOnLoad(){
		this.ui_left = this.node.getChildByName('left').getComponent(UITransform);
		this.ui_round_box = this.node.getChildByName('round-box').getComponent(UITransform);
		this.ui_round_list = [];
		this.ui_round_box.node.children.forEach(node=>{
			if(node.name=='item'){
				this.ui_round_list.push(node.getComponent(UITransform));
			}
		});
		this.ui_round_list.sort((a, b)=>a.node.position.x - b.node.position.x);

		this.va_left = new mtec.cc.VecAssist(this.ui_left.node);
		this.va_round_box = new mtec.cc.VecAssist(this.ui_round_box.node);
		this.va_round_list = this.ui_round_list.map(ui=>new mtec.cc.VecAssist(ui.node));

		this.va_left.vec.set(this.ui_left.node.position);
		this.va_round_box.vec.set(this.ui_round_box.node.position);
		this.va_round_list.forEach((va, i)=>va.vec.set(this.ui_round_list[i].node.position));

		this.ui_round_list.forEach(ui=>{
			let wgt = ui.getComponent(Widget);
			if(wgt){
				wgt.enabled = false;
				wgt.destroy();
			}
		});

		this.last_show_round = GGameDC.User.round;
	}

	protected start(){
		let wgt = this.node.getComponent(Widget);
		if(wgt) wgt.updateAlignment();

		this.va_left.vec.set(this.va_left.over_left, this.ui_left.node.position.y, this.ui_left.node.position.z);

		this.ui_left.node.setPosition(this.va_left.vec);

		this.item_space = this.node.getComponent(UITransform).width - this.ui_round_list[0].width * 3.5;
		this.item_space = this.item_space / 3;

		this.ui_round_box.setContentSize(this.node.getComponent(UITransform).width, this.ui_round_list[0].height);
		this.ui_round_box.node.setPosition(this.va_round_box.getPosition('center', 'top'));

		this.ui_round_list.forEach((ui, i)=>{
			let va = this.va_round_list[i];
			va.vec.set(va.right + (i - 3) * (this.item_space + ui.width), va.over_top, ui.node.position.z);
			ui.node.setPosition(va.vec);
		});


		this.renderLocalUI();

		this.node.active = false;
	}

	protected listening(){
		let list = [
			this.follow(GGameDC.Trigger, 'UITrans', (_, show)=>this.showUI(_, show), false),
		];

		return list;
	}

	private renderLocalUI(){
		this.ui_round_list.forEach((ui, i)=>{
			mtec.cc.skinPeeler(ui.node.getChildByName('status-pass'), GGameAssets.getLangTexture(1), {height: true});
			mtec.cc.skinPeeler(ui.node.getChildByName('status-curr'), GGameAssets.getLangTexture(0), {height: true});
			ui.node.getChildByName('lbl-round').getComponent(Label).string = GGameAssets.getLangText(19, i+1);
		});
	}

	private showUI(last: boolean, show: boolean){
		if(last == show){
			return void 0;
		}

		if(show){
			this.enter();
		}else{
			this.leave();
		}
	}

	private enter(duration?: number){
		let round = GGameDC.User.round;
		this.ui_left.node.getChildByName('label').getComponent(Label).string = GGameAssets.getLangText(19, round);

		AudioManager.playEffect(AudioManager.EAudio.EF_TRANSITION);
		this.node.active = true;
		duration = duration ?? 0.5;

		Tween.stopAllByTarget(this.ui_left.node);
		this.va_left.vec.x = this.va_left.over_left;
		this.ui_left.node.setPosition(this.va_left.vec);

		this.va_left.vec.x = this.va_left.left;
		tween(this.ui_left.node)
		.to(duration, {position: this.va_left.vec}, {easing: 'cubicOut'})
		.start();

		let speed_item = this.ui_round_list[0].height / duration;

		let curr_idx = round - 1;
		let last_idx = this.last_show_round - 1;
		if((curr_idx-last_idx) > 1){
			last_idx = curr_idx - 1;
		}

		Tween.stopAllByTarget(this.ui_round_box.node);
		this.va_round_box.getPosition('right', 'top');
		this.va_round_box.vec.x = this.va_round_box.right + (3 - Math.max(1, curr_idx)) * (this.item_space + this.ui_round_list[0].width);
		this.ui_round_box.node.setPosition(this.va_round_box.vec);

		this.ui_round_list.forEach((ui, index)=>{
			ui.node.active = index <= Math.max(1, curr_idx+1);
			if(!ui.node.active){
				return void 0;
			}

			let va = this.va_round_list[index];
			Tween.stopAllByTarget(ui.node);
			ui.node.setPosition(ui.node.position.x, va.over_top, va.vec.z);
			this.refreshRoundItemUI(ui.node, index < last_idx ? 'pass' : index == last_idx ? 'curr' : 'lock');

			if(index== last_idx){
				va.vec.y = va.top;
			}else{
				va.vec.y = va.top + 110;
			}

			let time = Vec3.subtract(this.calculate_v3, va.vec, ui.node.position).length() / speed_item;

			if(time > duration){
				duration = time;
			}

			tween(ui.node)
			.to(time, {position: va.vec}, {easing: 'bounceOut'})
			.start();
		});

		this.last_show_round = curr_idx;

		if(last_idx == curr_idx){
			mtec.delay(duration + 1.5, ()=>{
				GGameDC.Trigger.UITrans = false;
			});
			return void 0;
		}

		this.va_round_box.getPosition('right', 'top');
		this.va_round_box.vec.x = this.va_round_box.right + (3 - mtec.number.limit(curr_idx+1, 1, 3)) * (this.item_space + this.ui_round_list[0].width);

		tween(this.ui_round_box.node)
		.delay(duration + 0.2)
		.to(duration + 0.2, {position: this.va_round_box.vec})
		.start();

		this.scheduleOnce(()=>{
			this.ui_round_list.forEach((ui, index)=>{
				ui.node.active = index <= Math.max(1, curr_idx+1);
				if(!ui.node.active){
					return void 0;
				}

				if(![last_idx, curr_idx].includes(index)){
					return void 0;
				}
				Tween.stopAllByTarget(ui.node);

				let va = this.va_round_list[index];
				if(index == curr_idx){
					va.vec.y = va.top;
				}else if(index == last_idx){
					va.vec.y = va.top + 110;
				}

				tween(ui.node)
				.to(duration+0.2, {position: va.vec}, curr_idx == index ? {easing: 'bounceOut'} : void 0)
				.call(()=>this.refreshRoundItemUI(ui.node, index == curr_idx ? 'curr' : 'pass'))
				.start();
			});
		}, duration + 0.5);

		this.scheduleOnce(()=>{
			GGameDC.Trigger.UITrans = false;
		}, duration + 1.5);
	}

	private leave(duration?: number){
		duration = duration ?? 0.5;
		let speed = this.ui_round_list[0].height / duration;

		let curr_idx = GGameDC.User.round - 1;

		this.ui_round_list.forEach((ui, index)=>{
			if(!ui.node.active){
				return void 0;
			}

			let va = this.va_round_list[index];
			va.vec.y = va.over_top;
			let time = Vec3.subtract(this.calculate_v3, va.vec, ui.node.position).length() / speed;
			if(time > duration){
				duration = time;
			}

			Tween.stopAllByTarget(ui.node);

			let tw = tween(ui.node);

			if(index == curr_idx){
				tw = tw.delay(time * 0.5);
			}

			tw
			.to(time, {position: va.vec}, {easing: 'cubicOut'})
			.start();
		});

		Tween.stopAllByTarget(this.ui_left.node);
		this.va_left.vec.x = this.va_left.left;
		this.ui_left.node.setPosition(this.va_left.vec);

		this.va_left.vec.x = this.va_left.over_left;
		tween(this.ui_left.node)
		.to(duration, {position: this.va_left.vec}, {easing: 'cubicOut'})
		.call(()=>{
			this.node.active = false;
			GGameDC.Trigger.UIHome = true;
			GGameDC.Trigger.UIGame = true;
		}).start();
	}

	private refreshRoundItemUI(item: Node, type: 'pass' | 'curr' | 'lock'){
		let pass = type == 'pass';
		let lock = type == 'lock';
		let curr = type == 'curr';

		item.getChildByName('background').active = !curr;
		item.getChildByName('background-curr').active = curr;
		item.getChildByName('status-pass').active = pass;
		item.getChildByName('status-curr').active = curr;
		item.getChildByName('lock').active = lock;
	}
}

